﻿#include "guideTable.h"



GuideTable::GuideTable(QWidget* parent)
{
    this->setParent(parent);


    _layout = new QVBoxLayout(this);
    _layout_text = new QGridLayout(this);
    _table_plan = new QTableWidget(this);
    _table_data = new QTableWidget(this);

    _widget_text = new QWidget(this);

    _anaTool = new dataanatool();

    _table_plan->setEditTriggers(QAbstractItemView::NoEditTriggers);   // 设置每一行不可编辑
    _table_data->setEditTriggers(QAbstractItemView::NoEditTriggers);

    _label_Y  = new QLabel("Y:  R\xC2\xB2: 0.999, Y轴截距:0.00, 扩增效率:0.00, 斜率: 0.00", this);
    _label_AS  = new QLabel("AS: R\xC2\xB2: 0.999, Y轴截距:0.00, 扩增效率:0.00, 斜率: 0.00", this);
    _label_AL  = new QLabel("AL: R\xC2\xB2: 0.999, Y轴截距:0.00, 扩增效率:0.00, 斜率: 0.00", this);

    _warning_Y = new LabelResultInfo(this);
    _warning_AL = new LabelResultInfo(this);
    _warning_AS = new LabelResultInfo(this);

#ifdef Q_OS_ANDROID
    int fontId = QFontDatabase::addApplicationFont(":/FontStyle/AlibabaPuHuiTi-3-55-Regular.ttf");
    if (fontId != -1) {
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
        if (!fontFamilies.isEmpty()) {
            QString familyName = fontFamilies.first();
            QFont font(familyName, 16);
            _table_plan->setFont(font);
            _table_data->horizontalHeader()->setFont(font);
            _table_data->setFont(font);
            _label_Y->setFont(font);
            _label_AL->setFont(font);
            _label_AS->setFont(font);
        }
    }
#endif

    this->setStyleSheet("background: rgba(255,255,255,0.6); border-radius: 0px;");

    _label_Y->setStyleSheet("color: blue; background:rgba(255,255,255,0);");
    _label_AS->setStyleSheet("color: green; background:rgba(255,255,255,0);");
    _label_AL->setStyleSheet("color: rgba(233, 88, 0); background:rgba(255,255,255,0);");
    _widget_text->setStyleSheet("background:rgba(255,255,255,0.7);");


    _table_data->horizontalHeader()->setStyleSheet("QHeaderView::section{background:rgb(255, 255, 255);}");


    this->setLayout(_layout);
    _layout->setSpacing(0);
    _layout->addWidget(_table_plan);
    _layout->addWidget(_table_data);
    _layout->addWidget(_widget_text);
    _widget_text->setLayout(_layout_text);


    _layout_text->addWidget(_label_Y, 0, 0);
    _layout_text->addWidget(_label_AS, 0, 1);
    _layout_text->addWidget(_label_AL, 2, 0);
    _layout_text->addWidget(_warning_Y, 1, 0);
    _layout_text->addWidget(_warning_AS, 1, 1);
    _layout_text->addWidget(_warning_AL, 3, 0);

    _table_data->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    _table_data->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

}

void GuideTable::save(QString filePath){

    if(filePath.isEmpty()&&filePath.isNull()){
        return;
    }
    else
    {
        QXlsx::Document xlsx(filePath);
        createXlsx(xlsx);
        xlsx.saveAs(filePath);

    }
}


QTableWidget* GuideTable::getTable1(){
    QXlsx::Document xlsx;
    createXlsx(xlsx);
    // 表格转TableWidget
    xlsx.selectSheet("下游操作建议");
    delete _printTable1;
    _printTable1 = new QTableWidget(this);
    _printTable1->clear();
    int ROW1 = xlsx.dimension().rowCount();
    int COL1 = xlsx.dimension().columnCount();
    _printTable1->setRowCount(ROW1);
    _printTable1->setColumnCount(COL1);
    _printTable1->verticalHeader()->setHidden(true);
    _printTable1->horizontalHeader()->setHidden(true);
    for(int c = 0; c < COL1; c ++){
        for(int r = 0; r < ROW1; r ++){
            QString text = xlsx.read(r+1, c+1).toString();
            _printTable1->setItem(r, c, new QTableWidgetItem(text));
        }
    }
    return _printTable1;
}
QTableWidget* GuideTable::getTable2(){
    QXlsx::Document xlsx;
    createXlsx(xlsx);
    // 表格转TableWidget
    xlsx.selectSheet("加样表格");
    delete _printTable2;
    _printTable2 = new QTableWidget(this);
    int ROW2 = xlsx.dimension().rowCount();
    int COL2 = xlsx.dimension().columnCount();
    _printTable2->setRowCount(ROW2);
    _printTable2->setColumnCount(COL2);
    _printTable2->verticalHeader()->setHidden(true);
    _printTable2->horizontalHeader()->setHidden(true);
    for(int c = 0; c < COL2; c ++){
        for(int r = 0; r < ROW2; r ++){
            QString text = xlsx.read(r+1, c+1).toString();
            _printTable2->setItem(r, c, new QTableWidgetItem(text));
        }
    }
    return _printTable2;
}


void GuideTable::init(PCRState *state){
    if(!state){
        return;
    }
    pState = state;
    calculate();
    updateTable1();
    updateTable2();
    QList<int> nums = _anaTool->sl();
    if(nums.size() < 5){
        return;
    }
    pState->guideSum = nums[4];
    pState->guideCSTR = nums[0];
    pState->guideYSTR = nums[1];
    pState->guideMiniSTR = nums[2];
    pState->guideDilute = nums[3];
}

void GuideTable::calculate(){

    if(!pState){
        return;
    }

    if(!pState->canAnalysis || !pState->canGuide){
        qDebug() << "标准品不存在，无法计算指导建议";
    }

    QVector<QVector<QString>> inputData;
    foreach(PosiName posi, pState->posiList){
        foreach(ChannelName channel, pState->channelList){
            CurveName curve(channel, posi);
            QVector<QString> line;
            line.append(posi);
            line.append(pState->sampleInfo_posi[posi][1]);
            line.append(pState->sampleInfo_posi[posi][2]);
            line.append(channel);
            line.append(QString::number(pState->Ct[curve], 'f', 2));
            if(pState->concList.contains(curve)){
                line.append(QString::number(pState->concList[curve], 'f', 6));
            }else{
                if(pState->sampleInfo_posi.contains(curve.posi()) && pState->sampleInfo_posi[curve.posi()][2].contains("标准")){
                    pState->concList[curve] = pState->sampleInfo_posi[curve.posi()][3].toDouble();
                }else{
                    pState->concList[curve] = 0;
                }
                line.append(QString::number(pState->concList[curve], 'f', 6));
            }
            inputData.push_back(line);
        }
    }
    auto data1 = _anaTool->table1(inputData);
    _anaTool->table2(data1);

}

void GuideTable::updateTable1(){
    // 绘制表头
    _table_data->setColumnCount(14);
    _table_data->setWindowTitle("QTableWidget & Item");
    _table_data->resizeColumnsToContents();
    _table_data->resizeRowsToContents();
    QStringList header;
    header<<"序号"<<"孔位"<<"样本名称"<<"样本类型"<<"荧光染料"<<"CT值"<<"样本浓度\nng/μl"<<
            "总浓度\nng/μl"<<"男性浓度\nng/μl"<<"女性浓度\nng/μl"<<"性别情况"<<"男女浓度\n比例"<<"降解指数\nDI"<<"抑制指数\nICS";
    _table_data->setHorizontalHeaderLabels(header);
    _table_data->verticalHeader()->hide();//取消行号
    _table_data->show();


    // 内容
    QVector<QVector<QString>>& data1 = _anaTool->outtab1;
    _table_data->setRowCount(data1.size());
    for(int i = 0; i < data1.size(); i ++){
        for(int j = 0; j < data1[i].size(); j ++){
            _table_data->setItem(i, j+1, new QTableWidgetItem(data1[i][j]));
        }
    }

}

void GuideTable::updateTable2(){

    // 标题
    _table_plan->setColumnCount(13);
    _table_plan->setRowCount(2);
    _table_plan->setWindowTitle("QTableWidget & Item");
    _table_plan->horizontalHeader()->hide();//取消列号
    _table_plan->verticalHeader()->hide();//取消行号
    _table_plan->setItem(0,0,new QTableWidgetItem("序号"));
    _table_plan->setItem(0,1,new QTableWidgetItem("孔位"));
    _table_plan->setItem(0,2,new QTableWidgetItem("样本名称"));
    _table_plan->setItem(0,3,new QTableWidgetItem("检测方案"));
    _table_plan->setItem(0,4,new QTableWidgetItem("总稀释倍数"));
    _table_plan->setItem(0,5,new QTableWidgetItem("第一步稀释步骤"));
    _table_plan->setItem(1,5,new QTableWidgetItem("稀释倍数1"));
    _table_plan->setItem(1,6,new QTableWidgetItem("样品体积\n(μl)"));
    _table_plan->setItem(1,7,new QTableWidgetItem("稀释液体积\n(μl)"));
    _table_plan->setItem(0,8,new QTableWidgetItem("第二步稀释步骤"));
    _table_plan->setItem(1,8,new QTableWidgetItem("稀释倍数2"));
    _table_plan->setItem(1,9,new QTableWidgetItem("上一步稀释\n产物(μl)"));
    _table_plan->setItem(1,10,new QTableWidgetItem("稀释液体积\n(μl)"));
    _table_plan->setItem(0,11,new QTableWidgetItem("扩增上样体积"));
    _table_plan->setItem(0,12,new QTableWidgetItem("备注"));
    for(int r = 0; r <= 1; r ++){
        for(int c = 0; c <= 12; c ++){
            if(_table_plan->item(r, c) == nullptr){
                continue;
            }
            _table_plan->item(r, c)->setBackground(QColor("white"));
            _table_plan->item(r, c)->setTextAlignment(Qt::AlignCenter);
        }
    }

    // 内容
    QVector<QVector<QString>> data2 = _anaTool->sx(_typeTable2);
    _table_plan->setRowCount(data2.size() + 2);
    for(int i = 0; i < data2.size(); i ++){
        for(int j = 0; j < data2[i].size(); j ++){
            _table_plan->setItem(i+2, j+1, new QTableWidgetItem(data2[i][j]));
        }
    }


    _table_plan->setSpan(0, 0, 2, 1);
    _table_plan->setSpan(0, 1, 2, 1);
    _table_plan->setSpan(0, 2, 2, 1);
    _table_plan->setSpan(0, 3, 2, 1);
    _table_plan->setSpan(0, 4, 2, 1);
    _table_plan->setSpan(0, 5, 1, 3);
    _table_plan->setSpan(0, 8, 1, 3);
    _table_plan->setSpan(0, 11, 2, 1);
    _table_plan->setSpan(0, 12, 2, 1);
    _table_plan->show();
}

void GuideTable::fixRow(){
    _table_data->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
    _table_plan->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
}

void GuideTable::resizeRow(){

    double width = this->width() - 33;
    _table_data->setColumnWidth(0,  1.0 * width / 30.0);
    _table_data->setColumnWidth(1,  1.0 * width / 30.0);
    _table_data->setColumnWidth(2,  2.0 * width / 30.0);
    _table_data->setColumnWidth(3,  2.0 * width / 30.0);
    _table_data->setColumnWidth(4,  2.0 * width / 30.0);
    _table_data->setColumnWidth(5,  2.0 * width / 30.0);
    _table_data->setColumnWidth(6,  2.0 * width / 30.0);
    _table_data->setColumnWidth(7,  2.0 * width / 30.0);
    _table_data->setColumnWidth(8,  2.0 * width / 30.0);
    _table_data->setColumnWidth(9,  2.0 * width / 30.0);
    _table_data->setColumnWidth(10, 4.0 * width / 30.0);
    _table_data->setColumnWidth(11, 4.0 * width / 30.0);
    _table_data->setColumnWidth(12, 2.0 * width / 30.0);
    _table_data->setColumnWidth(13, 2.0 * width / 30.0);


    _table_plan->setColumnWidth(0,  1.0 * width / 30.0);
    _table_plan->setColumnWidth(1,  1.0 * width / 30.0);
    _table_plan->setColumnWidth(2,  2.0 * width / 30.0);
    _table_plan->setColumnWidth(3,  2.0 * width / 30.0);
    _table_plan->setColumnWidth(4,  2.0 * width / 30.0);
    _table_plan->setColumnWidth(5,  3.0 * width / 30.0);
    _table_plan->setColumnWidth(6,  2.5 * width / 30.0);
    _table_plan->setColumnWidth(7,  2.5 * width / 30.0);
    _table_plan->setColumnWidth(8,  3.0 * width / 30.0);
    _table_plan->setColumnWidth(9,  2.5 * width / 30.0);
    _table_plan->setColumnWidth(10, 2.5 * width / 30.0);
    _table_plan->setColumnWidth(11, 3.0 * width / 30.0);
    _table_plan->setColumnWidth(12, 3.0 * width / 30.0);

    _table_plan->resizeRowsToContents();
    _table_data->resizeRowsToContents();
}

void GuideTable::resizeEvent(QResizeEvent *event){
#ifdef Q_OS_ANDROID
    this->setMaximumWidth(this->parentWidget()->width());
#endif

    resizeRow();
}

void GuideTable::on_recalculate(){
    qDebug() << "触发下游操作建议重新计算 ---------->";
    QTime timer;
    timer.start();
    int last_time = 0;
    calculate();
    qDebug() << "执行计算时间" << timer.elapsed() - last_time;
    last_time = timer.elapsed();
    updateTable1();
    updateTable2();
    qDebug() << "更新表格时间" << timer.elapsed() - last_time;
    last_time = timer.elapsed();
    QList<int> nums = _anaTool->sl();
    if(nums.size() < 5){
        return;
    }
    pState->guideSum = nums[4];
    pState->guideCSTR = nums[0];
    pState->guideYSTR = nums[1];
    pState->guideMiniSTR = nums[2];
    pState->guideDilute = nums[3];
    qDebug() << "下游操作建议重新计算完成 ---------->" << "总时间" << timer.elapsed();
}

void GuideTable::on_sum_clicked(){
    _typeTable2 = "总数";
    updateTable2();
}
void GuideTable::on_CSTR_clicked(){
    _typeTable2 = "常STR";
    updateTable2();
}
void GuideTable::on_YSTR_clicked(){
    _typeTable2 = "Y-STR";
    updateTable2();
}
void GuideTable::on_miniSTR_clicked(){
    _typeTable2 = "mini-STR";
    updateTable2();
}
void GuideTable::on_dilute_clicked(){
    _typeTable2 = "稀释";
    updateTable2();
}


void GuideTable::createXlsx(QXlsx::Document &xlsx){
    QVector<QString> posiList;                      // 这两种格式还不兼容了 w(ﾟДﾟ)w
    foreach(QString posi, pState->posiList_filter){
        posiList.push_back(posi);
    }
    _anaTool->xyczjy(xlsx, posiList);
}


void GuideTable::on_filterChanged(){

    int lineIdx = 1;
    for(int row = 0; row < _table_data->rowCount(); row ++){

        if(_table_data->item(row, 1) == nullptr || _table_data->item(row, 2) == nullptr || _table_data->item(row, 3) == nullptr){
//            qDebug() << "TableData第" + QString::number(row) + "行数据为空";
            _table_data->hideRow(row);
            continue;
        }

        QString posi = _table_data->item(row, 1)->text();
        QString name = _table_data->item(row, 2)->text();
        QString type = _table_data->item(row, 3)->text();
        if(pState->posiList_filter.contains(posi) && pState->nameList_filter.contains(name) && pState->typeList_filter.contains(type)){
            _table_data->setItem(row, 0, new QTableWidgetItem(QString::number(lineIdx++)));
            _table_data->showRow(row);
        }else{
            _table_data->hideRow(row);
        }
    }

    lineIdx = 1;
    for(int row = 2; row < _table_plan->rowCount(); row ++){
        if(_table_plan->item(row, 1) == nullptr){
//            qDebug() << "TablePlan第" << QString::number(row) << "行数据为空";
            _table_plan->hideRow(row);
            continue;
        }
        QString posi = _table_plan->item(row, 1)->text();
        if(pState->posiList_filter.contains(posi)){
            _table_plan->setItem(row, 0, new QTableWidgetItem(QString::number(lineIdx++)));
            _table_plan->showRow(row);
        }else{
            _table_plan->hideRow(row);
        }
    }

}
void GuideTable::on_guidePageChanged(){

//    qDebug() << "更新GuidePage" << pState->guidePage;

    if(pState->guidePage == 1){
        on_sum_clicked();
    }else if(pState->guidePage == 2){
        on_CSTR_clicked();
    }else if(pState->guidePage == 3){
        on_YSTR_clicked();
    }else if(pState->guidePage == 4){
        on_miniSTR_clicked();
    }else{
        on_dilute_clicked();
    }

    on_filterChanged();
}

void GuideTable::refreshLabelResultInfo(){

    if(pState->E.contains("FAM") && pState->E.contains("ROX") && pState->E.contains("VIC") &&
       pState->standardLine.contains("FAM") && pState->standardLine.contains("ROX") && pState->standardLine.contains("VIC") &&
       pState->R2.contains("FAM") && pState->R2.contains("ROX") && pState->R2.contains("VIC")){
        _label_Y->setText(QString("Y: R\xC2\xB2: %3, Y轴截距: %4, 扩增效率:%1%, 斜率: %2").arg(QString::number((pState->E["FAM"]-1)*100, 'f', 2), QString::number(pState->standardLine["FAM"][0], 'f', 2), QString::number(pState->R2["FAM"], 'f', 3), QString::number(pState->standardLine["FAM"][1], 'f', 2)));
        _label_AL->setText(QString("AL: R\xC2\xB2: %3, Y轴截距: %4, 扩增效率:%1%, 斜率: %2").arg(QString::number((pState->E["ROX"]-1)*100, 'f', 2), QString::number(pState->standardLine["ROX"][0], 'f', 2), QString::number(pState->R2["ROX"], 'f', 3), QString::number(pState->standardLine["ROX"][1], 'f', 2)));
        _label_AS->setText(QString("AS: R\xC2\xB2: %3, Y轴截距: %4, 扩增效率:%1%, 斜率: %2").arg(QString::number((pState->E["VIC"]-1)*100, 'f', 2), QString::number(pState->standardLine["VIC"][0], 'f', 2), QString::number(pState->R2["VIC"], 'f', 3), QString::number(pState->standardLine["VIC"][1], 'f', 2)));

        QString text_Y, text_AL, text_AS;
        if((pState->E["FAM"]-1)*100 > 110 || (pState->E["FAM"]-1)*100 < 90){
            text_Y.append("E不合格 ");
        }if(pState->R2["FAM"] < 0.98){
            text_Y.append("R\xC2\xB2不合格 ");
        }
        if((pState->E["ROX"]-1)*100 > 110 || (pState->E["ROX"]-1)*100 < 90){
            text_AL.append("E不合格 ");
        }if(pState->R2["ROX"] < 0.98){
            text_AL.append("R\xC2\xB2不合格 ");
        }
        if((pState->E["VIC"]-1)*100 > 110 || (pState->E["VIC"]-1)*100 < 90){
            text_AS.append("E不合格 ");
        }if(pState->R2["VIC"] < 0.98){
            text_AS.append("R\xC2\xB2不合格 ");
        }

        if(text_Y != ""){
            _warning_Y->setVisible(true);
            _warning_Y->setText("Y: " + text_Y);
        }else{
            _warning_Y->setVisible(false);
        }
        if(text_AL != ""){
            _warning_AL->setVisible(true);
            _warning_AL->setText("AL: " + text_AL);
        }else{
            _warning_AL->setVisible(false);
        }
        if(text_AS != ""){
            _warning_AS->setVisible(true);
            _warning_AS->setText("AS: " + text_AS);
        }else{
            _warning_AS->setVisible(false);
        }

    }else{
        qDebug("更新扩增效率失败");
    }
}

void GuideTable::on_pageChanged(){



    this->setUpdatesEnabled(false);
    if(pState->curPage == PCRState::GUIDE_DATA){
//        qDebug() << "切换至表格1" << _table_data->rowCount() << _table_data->columnCount();
        _table_data->show();
        _table_plan->hide();
    }else{
//        qDebug() << "切换至表格2" << _table_plan->rowCount() << _table_plan->columnCount();
        _table_plan->show();
        _table_data->hide();
    }

    refreshLabelResultInfo();


    on_filterChanged();

    this->setUpdatesEnabled(true);

}
